home *** CD-ROM | disk | FTP | other *** search
- // main.cpp - Frog Pond Listing 3
- #include <frog.h>
-
- main()
- {
- PMF_VV pf = &Creature::move; // bound to a virtual
- Pond walden;
- Creature *p1;
- Creature *p2;
-
- p1 = Creature::newCreature(Tadpole("Wiggly") );
- walden.insert(p1);
- p2 = Creature::newCreature(Bullfrog("Croaker") );
- walden.insert(p2);
-
- cout << "First time -------------------\n";
- walden.activate( pf ); // Tell all creatures to move
- cout << "second time ------------------\n";
- walden.activate( pf ); // Tell all creatures to move
- cout << "third time -------------------\n";
- walden.activate( pf ); // Tell all creatures to move
-
- return 0;
- }
-
- First time -------------------
- WigglyAge 1 Swimming jerkily
- Croaker - I'm jumping
- second time ------------------
- Wiggly Age 2 Swimming jerkily still, but changing into Bullfrog
- Croaker - I'm jumping
- third time -------------------
- Wiggly - I'm jumping
- Croaker - I'm jumping
- // Frog.h
- #ifndef FROG_H
- #define FROG_H
- #include <iostream.h>
- #include <rw/gslist.h>
-
- class Creature
- {
- public:
- Creature(Creature *ptr);
- Creature(const Creature &c) : object(c.object) {}
- virtual void move();
- virtual Creature *clone() const;
- static Creature *newCreature(const Creature&);
- virtual const char *getname() const
- {return object->getname(); }
- virtual ~Creature();
- // void change(Creature *c);
- protected:
- Creature() { object = 0; } // invoked by derived
- Creature *object;
- static Creature *altered;
- };
-
- declare(GSlist,Creature)
-
- class Frog : public Creature
- {
- protected:
- const char *name;
- public:
- Frog(const char *p);
- Frog(const Frog &f);
- ~Frog();
- virtual void move() = 0;
- virtual const char *getname() const { return name; }
- Creature * clone() const;
- };
-
- class Tadpole : public Frog
- {
- int age;
- public:
- Tadpole(const char *name = "Noname Tadpole");
- void move();
- Tadpole(const Tadpole& t) : Frog(t), age(t.age) { }
- // invoke Frog copy ctor
- Creature * clone() const;
- };
-
- class Bullfrog : public Frog
- {
- public:
- Bullfrog(const char *name="Noname frog");
- Bullfrog(const Bullfrog &b) : Frog(b) {}
- void move() { cout << name << " - I'm jumping\n"; }
- Creature * clone() const { return new Bullfrog(*this); }
-
- class Pond
- {
- GSlist(Creature) list; // singly linked creature list
- public:
- void activate( void (Creature::*pf) () );
- void insert(Creature*);
- };
-
- typedef void (Creature::*PMF_VV)();
- #endif
- // Frog.cpp
- #include <stdlib.h>
- #include <frog.h>
- #include <string.h>
-
- Creature *Creature::altered = 0; // private static data
- void Pond::insert(Creature *f)
- {
- list.insert(f);
- }
-
- void Pond::activate( PMF_VV pmf_vv )
- {
- GSlistIterator(Creature) it(list);
- Creature *resident;
- while ( resident = (Creature *)it() )
- {
- (resident->*pmf_vv)();
- }
- }
-
- Creature *Creature::newCreature(const Creature& prototype)
- {
- Creature *C = new Creature(prototype.clone());
- // we must return an envelope, clone just makes a letter
- return C;
- }
-
-
- Creature * Tadpole::clone() const
- {
- Tadpole *t = new Tadpole(*this); // Tadpole copy ctor
- return t;
- }
-
- Creature::Creature(Creature *objptr)
- {
- object = objptr;
- }
-
- Creature::~Creature() { }
-
- Creature *Creature::clone() const
- {
- Creature *p = object->clone();
- Creature *envelope = new Creature(p);
- return envelope;
- }
-
- void Creature::move()
- {
- object->move();
- if ( altered )
- {
- delete object;
- object = altered;
- altered = 0;
- }
- }
-
- Creature * Frog::clone() const // never get here
- {
- return 0;
- }
-
- Frog::Frog(const char *n) : name(n) { }
-
- Frog::Frog(const Frog &f) : Creature(f), name (f.getname())
- {
- }
-
- Tadpole::Tadpole(const char *n) : Frog(n),age(0)
- {
- }
-
- Bullfrog::Bullfrog(const char *n) : Frog(n)
- {
- }
-
- void Tadpole::move()
- {
- age++;
- if ( age < 2 )
- cout << name << "Age " << age << " Swimming jerkily\n";
- else
- {
- cout << name << " Age " << age <<
- " Swimming jerkily still, but changing into Bullfrog\n";
- Creature *f=Creature::newCreature(Bullfrog(name));
- Creature::altered = f;
- }
- }
-
- Frog::~Frog() { }
-
-